﻿
Imports System.Math
Imports System.Drawing
Imports System.Windows.Forms
Imports System.IO

Public Class Form1


    Private Buffer_Block(15, 15) As Byte
    Private DCT_Block(15, 15) As Long
    Private RGB_Block(15, 15) As Long

    Private Const PI = 3.14159265358979
    Dim image1 As Bitmap 'New Bitmap("C:\Users\joko\My Projects\dct\images\I12P10347021-0001.jpg")
    Dim checkImage As Bitmap
    Dim currentBlock As Integer
    Dim imageSize
    Dim imageSizeCheckImage
    Dim masterImageArray As New List(Of BlockChars)
    Dim checkImageArray As New List(Of BlockChars)
    Dim savedFileName As String

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        masterImageArray = New List(Of BlockChars)
        CalculateDCT(image1, lblTotalDCT, masterImageArray)
        'image1.Dispose()
    End Sub

    Private Sub btnScanImage_Click(sender As System.Object, e As System.EventArgs) Handles btnScanImage.Click
        checkImageArray = New List(Of BlockChars)
        CalculateDCT(checkImage, lblDCTTestScan, checkImageArray)
        processBlockDifferences()
        'checkImage.Dispose()
    End Sub

    Private Function C(Num As Integer) As Double
        If Num = 0 Then
            C = 1 / Math.Sqrt(2)
        Else
            C = 1
        End If
        Return C
    End Function

    Private Sub Print_Buffer()
        Dim I As Integer, J As Integer, Output As String

        For I = 0 To 15
            Output = Buffer_Block(0, I) & vbTab

            For J = 1 To 15
                Output = Output & Buffer_Block(J, I) & vbTab
            Next J
        Next I

    End Sub

    Private Function Print_DCT(lblDCToutPut As Label) As Integer
        Dim I As Integer, J As Integer, Output As String
        'DataGridView1.ColumnCount = 16
        Dim totalDCT As Integer

        For I = 0 To 15
            'DataGridView1.Rows.Add()
            Output = DCT_Block(0, I)
            'DataGridView1.Rows(I).Cells(0).Value = Output
            For J = 1 To 15
                If DCT_Block(0, 1) Or
                    DCT_Block(0, 2) Or
                    DCT_Block(0, 3) Or
                    DCT_Block(1, 0) Or
                    DCT_Block(1, 1) Or
                    DCT_Block(1, 2) Or
                    DCT_Block(1, 3) Or
                    DCT_Block(2, 0) Or
                    DCT_Block(2, 1) Or
                    DCT_Block(2, 2) Or
                        DCT_Block(2, 3) Or
                        DCT_Block(3, 0) Or
                    DCT_Block(3, 1) Or
                    DCT_Block(3, 2) Or
                        DCT_Block(3, 3) Then



                    Output = DCT_Block(J, I)
                End If

                totalDCT += CInt(Output)
                'DataGridView1.Rows(I).Cells(J).Value = Output
            Next J
            'Output &= ControlChars.Lf
            'Label1.Text &= Output
        Next I
        totalDCT = totalDCT / 15 'DCT_Block.Length - 1
        'lblDCToutPut.Text = totalDCT
        Return totalDCT
    End Function

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    End Sub

    Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
        Dim tifimage As Image = Image.FromFile("D:\Test Projects\New\image compare\I12P10347021-0001.jpg") 'indexed format image.
        Dim NonIndexedImage As New Bitmap(tifimage.Width, tifimage.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

        Dim g As Graphics = Graphics.FromImage(CType(NonIndexedImage, Image))

        g.DrawImage(tifimage, 0, 0, tifimage.Width, tifimage.Height)
        g.Dispose()
        tifimage.Dispose()


        'now you can setpixel on the tif image with the NonIndexedImage object.


        Dim processBlockNumber As Integer = TextBox1.Text
        Dim blockCounter As Integer = 1
        For j = 0 To (imageSize.height / 8) - 1
            For i = 0 To (imageSize.width / 8) - 1

                If blockCounter = processBlockNumber Then
                    Dim xctr As Integer = 0
                    For xx = 0 + (i * 8) To 7 + (i * 8)
                        Dim yctr As Integer = 0
                        For yy = 0 + (j * 8) To 7 + (j * 8)
                            If DCT_Block(xctr, yctr) <> 0 Then
                                NonIndexedImage.SetPixel(xx, yy, Color.Red) ' Color.FromArgb(rc, gc, bc))
                            End If

                            yctr += 1

                        Next
                        xctr += 1

                    Next


                End If
                blockCounter += 1

            Next
        Next

        NonIndexedImage.Save("D:\Test Projects\New\image compare\xxxI12P10347021-0001.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)



        'Dim g As Graphics = Graphics.FromImage(CType(NonIndexedImage, Image))

        'g.DrawImage(Image.FromFile("D:\Test Projects\New\image compare\I12P10347021-0001.jpg"), 0, 0)
        'g.Dispose()
        'putpixels()

        'NonIndexedImage.Save("D:\Test Projects\New\image compare\xxxI12P103415021-0001.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)


    End Sub
    'Public Sub putpixels()
    '    'Dim x As Integer
    '    'Dim y As Integer
    '    'Dim rc As Integer
    '    'Dim gc As Integer
    '    'Dim bc As Integer

    '    'For x = 0 To 15
    '    '    For y = 0 To 15
    '    '        'rc = yuvtor(pixelvaluesY(x, y), pixelvaluesV(x, y))
    '    '        'gc = yuvtog(pixelvaluesY(x, y), pixelvaluesU(x, y), pixelvaluesV(x, y))
    '    '        'bc = yuvtob(pixelvaluesY(x, y), pixelvaluesU(x, y))

    '    '        NonIndexedImage.SetPixel(x, y, Color.AliceBlue) ' Color.FromArgb(rc, gc, bc))
    '    '    Next y

    '    'Next x

    '    Dim processBlockNumber As Integer = TextBox1.Text
    '    Dim blockCounter As Integer = 1
    '    For j = 0 To (imageSize.Width / 16) - 1
    '        For i = 0 To (imageSize.Height / 16) - 1

    '            If blockCounter = processBlockNumber Then
    '                Dim yctr As Integer = 0
    '                For yy = 0 + (i * 16) To 15 + (i * 16)
    '                    Dim xctr As Integer = 0
    '                    For xx = 0 + (j * 16) To 15 + (j * 16)
    '                        NonIndexedImage.SetPixel(xx, yy, Color.AliceBlue) ' Color.FromArgb(rc, gc, bc))
    '                        xctr += 1
    '                    Next
    '                    yctr += 1
    '                Next


    '            End If
    '            blockCounter += 1

    '        Next
    '    Next
    'End Sub

    Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click
        OpenFileDialog1.Title = "Please Select a File"
        OpenFileDialog1.InitialDirectory = "C:temp"

        OpenFileDialog1.ShowDialog()
    End Sub

    Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
        OpenFileDialog1.OpenFile()
        TextBoxMaster.Text = OpenFileDialog1.FileName.ToString()
        image1 = Image.FromFile(TextBoxMaster.Text)
    End Sub

    Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
        ofdCheckFile.Title = "Please Select a File"
        ofdCheckFile.InitialDirectory = "C:temp"
        ofdCheckFile.ShowDialog()
    End Sub

    Private Sub OpenFileDialog2_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ofdCheckFile.FileOk

        ofdCheckFile.OpenFile()
        TextBoxCheckImage.Text = ofdCheckFile.FileName.ToString()
        checkImage = Image.FromFile(TextBoxCheckImage.Text)
    End Sub

    Sub CalculateDCT(imageToCalculate As Bitmap, lblDCToutPut As Label, imgArray As List(Of BlockChars))
        imageSize = imageToCalculate.Size
        DataGridView1.Rows.Clear()
        Dim numberofBlocks = (imageSize.Width / 16) * (imageSize.Height / 16)
        'Dim masterImageArray(imageSize.Width, imageSize.Height, Round(numberofBlocks))

        Dim processBlockNumber As Integer = TextBox1.Text
        Dim blockCounter As Integer = 1
        For j = 0 To (imageSize.height / 16) - 1
            For i = 0 To (imageSize.width / 16) - 1

                'For blockCounter = 1 To processBlockNumber + 1
                'Label2.Text = j
                'Label3.Text = i

                Dim xctr As Integer = 0
                For xx = 0 + (i * 16) To 15 + (i * 16)
                    Dim yctr As Integer = 0
                    For yy = 0 + (j * 16) To 15 + (j * 16)
                        Buffer_Block(xctr, yctr) = (0.299 * imageToCalculate.GetPixel(xx, yy).R) + (0.5815 * imageToCalculate.GetPixel(xx, yy).G) + (0.114 * imageToCalculate.GetPixel(xx, yy).B)
                        'RGB_Block(xctr, yctr) = imageToCalculate.GetPixel(xx, yy).ToArgb
                        yctr += 1
                    Next
                    xctr += 1
                Next

                Dim Temp As Double = 0
                Dim U As Integer, V As Integer, X As Integer, Y As Integer = 0

                'Print_Buffer()

                For U = 0 To 15
                    For V = 0 To 15
                        Temp = 0

                        For X = 0 To 15
                            For Y = 0 To 15
                                Temp = Temp + (Buffer_Block(X, Y)) * _
               Cos((((2 * X) + 1) * U * PI) / 32) * _
               Cos((((2 * Y) + 1) * V * PI) / 32)

                                'Temp = Temp + (Cos(PI * ((2 * X) + 1) * U / 16) * Cos(PI * ((2 * Y) + 1) * V / 16) * Buffer_Block(X, Y))
                            Next Y
                        Next X

                        DCT_Block(U, V) = C(U) * C(V) * Temp / 8
                    Next V
                Next U


                imgArray.Add(New BlockChars(blockCounter, Print_DCT(lblDCToutPut)))

                'For X = 0 To 7
                '    For Y = 0 To 7
                '        Temp = 0

                '        For U = 0 To 7
                '            For V = 0 To 7
                '                Temp = Temp + ((C(U) / 2) * (C(V) / 2) * Cos(PI * (2 * X + 1) * U / 16) * Cos(PI * (2 * Y + 1) * V / 16) * DCT_Block(U, V))
                '            Next V
                '        Next U

                '        Buffer_Block(X, Y) = Temp
                '    Next Y
                'Next X

                'Print_Buffer()
                blockCounter += 1
                'Next
                'Exit Sub

            Next
        Next
    End Sub

    Sub processBlockDifferences()
        Dim tifimage As Image = Image.FromFile(TextBoxCheckImage.Text) 'indexed format image.
        Dim NonIndexedImage As New Bitmap(tifimage.Width, tifimage.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

        Dim g As Graphics = Graphics.FromImage(CType(NonIndexedImage, Image))

        g.DrawImage(tifimage, 0, 0, tifimage.Width, tifimage.Height)
        g.Dispose()
        tifimage.Dispose()


        Dim ctrBlock As Integer = masterImageArray.Count - 1
        For ctr = 0 To ctrBlock
            If Math.Abs(masterImageArray(ctr).dctValue - checkImageArray(ctr).dctValue) > 1 Then
                Dim processBlockNumber As Integer = masterImageArray(ctr).blockNumber
                Dim blockCounter As Integer = 1
                For j = 0 To (imageSize.height / 16) - 1
                    For i = 0 To (imageSize.width / 16) - 1
                        If blockCounter = processBlockNumber Then
                            Dim xLine As Integer = 0
                            For xx = 0 + (i * 16) To 15 + (i * 16)
                                Dim yLine As Integer = 0
                                For yy = 0 + (j * 16) To 15 + (j * 16)
                                    If (xLine = 0 OrElse xLine = 15) OrElse (yLine = 0 OrElse yLine = 15) Then
                                        NonIndexedImage.SetPixel(xx, yy, Color.Red) ' Color.FromArgb(rc, gc, bc))                                    
                                    End If
                                    yLine += 1
                                Next
                                xLine += 1
                            Next
                        End If
                        blockCounter += 1
                    Next
                Next
            End If
            'If Math.Abs(masterImageArray(ctr).dctValue - checkImageArray(ctr).dctValue) > 100 Then
            '    Dim processBlockNumber As Integer = masterImageArray(ctr).blockNumber
            '    Dim blockCounter As Integer = 1
            '    For j = 0 To (imageSize.height / 16) - 1
            '        For i = 0 To (imageSize.width / 16) - 1
            '            If blockCounter = processBlockNumber Then
            '                Dim xLine As Integer = 0
            '                For xx = 0 + (i * 16) To 15 + (i * 16)
            '                    Dim yLine As Integer = 0
            '                    For yy = 0 + (j * 16) To 15 + (j * 16)
            '                        If (xLine = 0 OrElse xLine = 15) OrElse (yLine = 0 OrElse yLine = 15) Then
            '                            NonIndexedImage.SetPixel(xx, yy, Color.Red) ' Color.FromArgb(rc, gc, bc))                                    
            '                        End If
            '                        yLine += 1
            '                    Next
            '                    xLine += 1
            '                Next
            '            End If
            '            blockCounter += 1
            '        Next
            '    Next
            'End If
        Next
        savedFileName = Path.GetDirectoryName(TextBoxCheckImage.Text) & "xxx" & ofdCheckFile.SafeFileName
        NonIndexedImage.Save(savedFileName, System.Drawing.Imaging.ImageFormat.Jpeg)

    End Sub

    Structure BlockChars
        Public blockNumber As Integer
        Public dctValue As Integer
        Public Sub New(blockNumber As Integer, dctValue As Integer)
            Me.blockNumber = blockNumber
            Me.dctValue = dctValue
        End Sub
    End Structure

    Private Sub btnStartCompare_Click(sender As System.Object, e As System.EventArgs) Handles btnStartCompare.Click
        BackgroundWorker1.RunWorkerAsync()
        lblStoredImage.Text = "Scanning..."
    End Sub


    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
      ByVal e As System.ComponentModel.DoWorkEventArgs) _
      Handles BackgroundWorker1.DoWork
        ' Do some time-consuming work on this thread.
        masterImageArray = New List(Of BlockChars)
        CalculateDCT(image1, lblTotalDCT, masterImageArray)
        checkImageArray = New List(Of BlockChars)
        CalculateDCT(checkImage, lblDCTTestScan, checkImageArray)
        processBlockDifferences()


        Dim MyImage As Bitmap
        PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
        MyImage = New Bitmap(Image.FromFile(savedFileName))
        PictureBox1.Image = CType(MyImage, Image)


        
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, _
           ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
           Handles BackgroundWorker1.RunWorkerCompleted
        ' Called when the BackgroundWorker is completed.
        lblStoredImage.Text = savedFileName
        MessageBox.Show(" Finished processing image.")


    End Sub

End Class